package com.example.encroption;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;


//对称加密:DES(8),AES(16),3DES(24)
public class MainActivity extends AppCompatActivity {
    private EditText input,pw;
    private TextView showInfo;
    private String encryptResult=null;
    private  String decryptResult=null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();

    }

    private void initView() {
        input= (EditText) findViewById(R.id.input);
        pw= (EditText) findViewById(R.id.pasword);
        showInfo= (TextView) findViewById(R.id.showInfo);
    }

    public void encropt(View view) {
        String data=input.getText().toString().trim();
        String pw=this.pw.getText().toString().trim();


        switch (view.getId()){
            case R.id.desEncrypt:
                encryptResult = encrypt("DES",data,pw);

                showInfo.setText("DES加密的内容是："+data
                +",加密的结果是:"+encryptResult);

                break;

            case R.id.desDecrypt://解密
               decryptResult = decrypt("DES",encryptResult,pw);
                showInfo.setText("DES解密的结果是:"+decryptResult);

                break;

            case R.id.desedeEncrypt://3Des加密

                //密码长度24位
                encryptResult=encrypt("DESede",data,pw);

                showInfo.setText("DES加密的内容是："+data
                        +",加密的结果是:"+encryptResult);
                break;

            case R.id.desedeDecrypt://3des解密
                decryptResult = decrypt("DESede",encryptResult,pw);
                showInfo.setText("3DES解密的结果是:"+decryptResult);
                break;

            case R.id.aesEncrypt://aes加密,美国军方加密的工具
                //密码长度16位
                encryptResult=encrypt("AES",data,pw);

                showInfo.setText("AES加密的内容是："+data
                        +",加密的结果是:"+encryptResult);
                break;

            case R.id.aesDecrypt:
                decryptResult = decrypt("AES",encryptResult,pw);
                showInfo.setText("AES解密的结果是:"+decryptResult);

                break;

        }

    }

    private String decrypt(String type, String data, String pw) {
        switch (type) {
            case "DES":
                try {
                    //1/获取加密所对应的类,加密引擎
                    Cipher cipher = Cipher.getInstance(type);

                    //2/对加密引擎进行初始化,告诉他密码,
                    if (pw.getBytes().length != 8) {
                        throw new Exception("密码长度必须为8位");
                    }
                    Key key = new SecretKeySpec(pw.getBytes(), type);
                    cipher.init(Cipher.DECRYPT_MODE, key);

                    //3/执行解密
                    if (!TextUtils.isEmpty(data)) {//data不为空，并且长度不为0
                        //base64的逆运算,加密时，为了内容不乱码，进行了Base64编码
                        //解密的内容，就是经过Base64编码
                        byte[] decode = Base64.decode(data.getBytes(), Base64.DEFAULT);
                        byte[] decryptBytes = cipher.doFinal(decode);

                        //返回相应的数据
                        return new String(decryptBytes);
                    }
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;

            case "DESede":
                try {
                    //1/获取加密所对应的类,加密引擎
                    Cipher cipher = Cipher.getInstance(type);

                    //2/对加密引擎进行初始化,告诉他密码,
                    if (pw.getBytes().length != 24) {
                        throw new Exception("密码长度必须为24位");
                    }
                    Key key = new SecretKeySpec(pw.getBytes(), type);
                    cipher.init(Cipher.DECRYPT_MODE, key);

                    //3/执行解密
                    if (!TextUtils.isEmpty(data)) {//data不为空，并且长度不为0
                        //base64的逆运算,加密时，为了内容不乱码，进行了Base64编码
                        //解密的内容，就是经过Base64编码
                        byte[] decode = Base64.decode(data.getBytes(), Base64.DEFAULT);
                        byte[] decryptBytes = cipher.doFinal(decode);

                        //返回相应的数据
                        return new String(decryptBytes);
                    }
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                break;

            case "AES":
                try {
                    //1/获取加密所对应的类,加密引擎
                    Cipher cipher = Cipher.getInstance(type);

                    //2/对加密引擎进行初始化,告诉他密码,
                    if (pw.getBytes().length != 16) {
                        throw new Exception("16");
                    }
                    Key key = new SecretKeySpec(pw.getBytes(), type);
                    cipher.init(Cipher.DECRYPT_MODE, key);

                    //3/执行解密
                    if (!TextUtils.isEmpty(data)) {//data不为空，并且长度不为0
                        //base64的逆运算,加密时，为了内容不乱码，进行了Base64编码
                        //解密的内容，就是经过Base64编码
                        byte[] decode = Base64.decode(data.getBytes(), Base64.DEFAULT);
                        byte[] decryptBytes = cipher.doFinal(decode);

                        //返回相应的数据
                        return new String(decryptBytes);
                    }
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }



                break;

        }
                return null;
    }


    //加密三种方式
    private String encrypt(String type, String data, String pw) {
        switch (type){
            case "DES":
                try {
                    //1/获取加密所对应的类,加密引擎
                    Cipher cipher=Cipher.getInstance(type);

                    //2/对加密引擎进行初始化,告诉他密码,
                    if(pw.getBytes().length!=8){
                        throw  new Exception("密码长度不符合要求，长度必须为8位");
                    }
                    Key key=new SecretKeySpec(pw.getBytes(),type);
                    cipher.init(Cipher.ENCRYPT_MODE,key);

                    //3/执行加密
                    if (!TextUtils.isEmpty(data)) {//data不为空，并且长度不为0
                        byte[] encryptBytes = cipher.doFinal(data.getBytes());
                        byte[] base64 = Base64.encode(encryptBytes, Base64.DEFAULT);

                        return new String(base64);
                    }

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }


                break;

            case "DESede":
                try {
                    //1/获取加密所对应的类,加密引擎
                    Cipher cipher=Cipher.getInstance(type);

                    //2/对加密引擎进行初始化,告诉他密码,
                    if(pw.getBytes().length!=24){
                        throw  new Exception("密码长度不符合要求，长度必须为24位");
                    }
                    Key key=new SecretKeySpec(pw.getBytes(),type);
                    cipher.init(Cipher.ENCRYPT_MODE,key);

                    //3/执行加密
                    if (!TextUtils.isEmpty(data)) {//data不为空，并且长度不为0
                        byte[] encryptBytes = cipher.doFinal(data.getBytes());
                        byte[] base64 = Base64.encode(encryptBytes, Base64.DEFAULT);
                        return new String(base64);
                    }

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                break;

            case "AES":

                try {
                    //1/获取加密所对应的类,加密引擎
                    Cipher cipher=Cipher.getInstance(type);

                    //2/对加密引擎进行初始化,告诉他密码,
                    if(pw.getBytes().length!=16){
                        throw  new Exception("密码长度不符合要求，长度必须为16位");
                    }
                    Key key=new SecretKeySpec(pw.getBytes(),type);
                    cipher.init(Cipher.ENCRYPT_MODE,key);

                    //3/执行加密
                    if (!TextUtils.isEmpty(data)) {//data不为空，并且长度不为0
                        byte[] encryptBytes = cipher.doFinal(data.getBytes());
                        byte[] base64 = Base64.encode(encryptBytes, Base64.DEFAULT);

                        return new String(base64);
                    }

                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (NoSuchPaddingException e) {
                    e.printStackTrace();
                } catch (InvalidKeyException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }


                break;

            default:
                try {
                    throw new Exception("加密的类型不匹配,请选择以下方式加密:DES,AES,DESede");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
        }
        return null;
    }
}
